package com.loutick.pay.controller;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.security.MessageDigest;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.jdom.JDOMException;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSON;
import com.alipay.config.AlipayConfig;
import com.alipay.util.AlipayNotify;
import com.alipay.util.AlipaySubmit;
import com.alipay.util.UtilDate;
import com.loutick.basicforapp.message.BasicMessage;
import com.loutick.pay.entity.TOrder;
import com.loutick.pay.entity.TPamentlog;
import com.loutick.pay.jsonbean.PayJsonMainBean;
import com.loutick.pay.jsonbean.PayRequestBean;
import com.loutick.pay.message.RechargeForWeixinJson;
import com.loutick.pay.message.RechargeForWeixinMessage;
import com.loutick.pay.message.RechargeMessage;
import com.loutick.pay.service.IPamentlog;
import com.weixin.util.CommonUtil;
import com.weixin.util.ConfigUtil;
import com.weixin.util.PayCommonUtil;
import com.weixin.util.XMLUtil;

@Controller
@RequestMapping("/pay")
public class PayController {
	private static Logger logger = Logger.getLogger(PayController.class);
	
	@Resource
	private IPamentlog pamentlogService;
	
	@RequestMapping("/payapi")
	public @ResponseBody Map<String , Object> toPayApi(@RequestParam String sessionId ,@RequestParam String message,HttpServletRequest request,Model model){
		//返回结果集
		Map<String , Object> modelMap = new HashMap<String , Object>();
		PayRequestBean basicRequestBean = null;
		PayJsonMainBean jsonMainBean = null;
		try {
			basicRequestBean = JSON.parseObject(message,PayRequestBean.class);
			jsonMainBean = basicRequestBean.getFirstReq() ;
		} catch (Exception e) {
			BasicMessage b = new BasicMessage();
			b.setCode("1");
			b.setMsg("message参数解析出错"); 
			modelMap.put("res", b);
			return modelMap;
		}
		
		String reqType = jsonMainBean.getReqType() ;
		if(reqType.equals("1010")){
			return recharge(jsonMainBean);
		}
		else if(reqType.equals("1011")){
			return payorder(jsonMainBean);
		}else if(reqType.equals("1012"))
		{
			return order(jsonMainBean);
		}
		
		return modelMap;
	}
	
	
	@RequestMapping("/notify")
	public void notifytaobao(HttpServletRequest request,HttpServletResponse response,Model model){
		
//		logger.error("支付宝 返回 结果信息");
//		Map<String,String> params = new HashMap<String,String>();
//		Map requestParams = request.getParameterMap();
//		String resultString = "";
//		TPamentlog tPamentlog = null;
//		for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
//			String name = (String) iter.next();
//			String[] values = (String[]) requestParams.get(name);
//			String valueStr = "";
//			for (int i = 0; i < values.length; i++) {
//				valueStr = (i == values.length - 1) ? valueStr + values[i]
//						: valueStr + values[i] + ",";
//			}
//			//乱码解决，这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
//			//valueStr = new String(valueStr.getBytes("ISO-8859-1"), "gbk");
//			params.put(name, valueStr);
//		}
//		//商户订单号
//		String out_trade_no = request.getParameter("out_trade_no");
//		//支付宝交易号
//		String trade_no = request.getParameter("trade_no");
//		//交易状态
//		String trade_status =request.getParameter("trade_status");
//		
//		logger.error("支付返回值 out_trade_no =" + out_trade_no   );
//		logger.error("支付返回值 trade_status =" + trade_status   );
//		
//		if(AlipayNotify.verify(params)){//验证成功
//
//			if(trade_status.equals("TRADE_FINISHED")){
//				//判断该笔订单是否在商户网站中已经做过处理
//					//如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
//					//请务必判断请求时的total_fee、seller_id与通知时获取的total_fee、seller_id为一致的
//					//如果有做过处理，不执行商户的业务程序
//				logger.error("支付状态成功 trade_status = TRADE_FINISHED"   );
//				resultString = pamentlogService.rechargeLog(out_trade_no,trade_no);
//				
//				//注意：
//				//退款日期超过可退款期限后（如三个月可退款），支付宝系统发送该交易状态通知
//			} else if (trade_status.equals("TRADE_SUCCESS")){
//				//判断该笔订单是否在商户网站中已经做过处理
//					//如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
//					//请务必判断请求时的total_fee、seller_id与通知时获取的total_fee、seller_id为一致的
//					//如果有做过处理，不执行商户的业务程序
//				
//				logger.error("支付宝通知 trade_status = TRADE_SUCCESS"   );
//
//			}
//
//			logger.info("支付宝通知 success"   );	
//			System.out.println("success");	//请不要修改或删除
//
//			//////////////////////////////////////////////////////////////////////////////////////////
//		}else{//验证失败
//			System.out.println("fail");
//			logger.info("支付宝通知 fail"   );	
//		}
		try {
			//获取支付宝POST过来反馈信息
			Map<String,String> params = new HashMap<String,String>();
			Map requestParams = request.getParameterMap();
			String resultString = "";
			for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
				String name = (String) iter.next();
				String[] values = (String[]) requestParams.get(name);
				String valueStr = "";
				for (int i = 0; i < values.length; i++) {
					valueStr = (i == values.length - 1) ? valueStr + values[i]
							: valueStr + values[i] + ",";
				}
				//乱码解决，这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
				valueStr = new String(valueStr.getBytes("ISO-8859-1"), "gbk");
				params.put(name, valueStr);
			}
			
			//获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表(以下仅供参考)//
			//商户订单号
			String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"),"UTF-8");
			//支付宝交易号
			String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"),"UTF-8");
			//交易状态
			String trade_status = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"),"UTF-8");
	
			//获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表(以上仅供参考)//
			logger.error("准备修改 充值记录");
			if(AlipayNotify.verify(params)){//验证成功
				
				if(trade_status.equals("TRADE_FINISHED")){
					logger.error("TRADE_FINISHED");
				} else if (trade_status.equals("TRADE_SUCCESS")){
					logger.error("TRADE_SUCCESS");
					resultString = pamentlogService.rechargeLog(out_trade_no,trade_no);
				}
	
				//——请根据您的业务逻辑来编写程序（以上代码仅作参考）——
				logger.error("充值  = success");	
//				out.print("success");	//请不要修改或删除
				try {
					response.getOutputStream().write(new String("success").getBytes());
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				//////////////////////////////////////////////////////////////////////////////////////////
			}else{//验证失败
	//			out.print("fail");
				logger.error("fail");
			}
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	@RequestMapping("/notifyweixin")
	public void notifyweixin(HttpServletRequest request,HttpServletResponse response,Model model){
		logger.error("微信 返回 结果信息");
		try {
			InputStream inputStream = request.getInputStream();
			ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
			byte[] buffer = new byte[1024] ;
			int len = 0 ;
			while((len = inputStream.read(buffer))!=-1){
				outputStream.write(buffer,0,len);
			}
			System.out.println("成功");
			outputStream.close();
			inputStream.close();
			String resultString = new String(outputStream.toByteArray(),"utf-8");
			Map<Object,Object> map = XMLUtil.doXMLParse(resultString);
			for(Object keyValue:map.keySet()){
				System.out.println(keyValue+"="+map.get(keyValue));
			}
			if(map.get("return_code").toString().equalsIgnoreCase("SUCCESS")){
				//数据库处理
				response.getWriter().write(PayCommonUtil.setXML("SUCCESS", ""));
				System.out.println("-----" + PayCommonUtil.setXML("SUCCESS", ""));
				String out_trade_no = (String)map.get("out_trade_no");
				String transaction_id = (String)map.get("transaction_id");
				String result = pamentlogService.rechargeLog(out_trade_no,transaction_id);
				logger.info("微信支付状态成功 return_code = SUCCESS"   );
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (JDOMException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	
	private Map<String , Object> order(PayJsonMainBean jsonObject){
		Map<String , Object> modelMap = new HashMap<String , Object>();
		String channelID = jsonObject.getChannelID();
		String thdOrderID = jsonObject.getThdOrderID();
		String money = jsonObject.getMoney();
		
		TOrder order = new TOrder();
		order.setMoney(Integer.parseInt(money));
		order.setThdorderid(thdOrderID);
		order.setChannelid(channelID);
		int result = pamentlogService.insertOrder(order);
		if(result>0){
			BasicMessage t = new BasicMessage();
			t.setCode("1");
			t.setMsg("该手机号已经注册");
			modelMap.put("res", t);
			return modelMap;
		}else{
			BasicMessage t = new BasicMessage();
			t.setCode("0");
			t.setMsg("成功");
			modelMap.put("res", t);
		}
		
		return modelMap;
	}
	
	//充值提交接口
	private Map<String , Object> recharge(PayJsonMainBean jsonObject){
		Map<String , Object> modelMap = new HashMap<String , Object>();
		String userID = jsonObject.getUserID();
		String payType = jsonObject.getPayType();
		String moneyString  = jsonObject.getMoney();
		logger.error("充值信息：=== userid:"+userID + "  payType:"+payType+"  moneyString:"+moneyString );
		String out_trade_no = UtilDate.getOrderNum() ;
		String subject = "recharge";
		String bodyString = "recharge";
		
		TPamentlog  tp = new TPamentlog();
		tp.setOuttradesn(out_trade_no) ;
		tp.setPayamount(Integer.valueOf(moneyString));
		tp.setUserid(Integer.valueOf(userID));
		tp.setPaytype(payType);
		//获取充值账户号
//		tp.setUseraccountid(0);
		tp.setPaymentname("recharge");
		tp.setPaytotype("20");
		tp.setPaystatus(0);
		logger.error("userid :" + userID);
		pamentlogService.insertPamentlog(tp,Integer.valueOf(userID));
		
		String payStr = "" ;
		
		if(payType.equals("2")){
			Map<String, String> sParaTemp = new HashMap<String, String>();
			sParaTemp.put("service", AlipayConfig.service);
	        sParaTemp.put("partner", AlipayConfig.partner);
	        sParaTemp.put("seller_id", AlipayConfig.seller_id);
	        sParaTemp.put("_input_charset", AlipayConfig.input_charset);
			sParaTemp.put("payment_type", AlipayConfig.payment_type);
			sParaTemp.put("notify_url", AlipayConfig.notify_url);
			sParaTemp.put("out_trade_no", out_trade_no);
			sParaTemp.put("subject", subject);
			sParaTemp.put("body", bodyString);
			BigDecimal a= new BigDecimal(moneyString);
			BigDecimal c= new BigDecimal("100");
			BigDecimal bigDecimal = a.divide(c,2,BigDecimal.ROUND_HALF_EVEN );
			sParaTemp.put("total_fee", bigDecimal+"");
//			logger.error("支付宝  total_fee:" +moneyString+"处理后金额:"+ bigDecimal  );
			payStr = AlipaySubmit.buildStr(sParaTemp) ;
			
			RechargeMessage rm = new RechargeMessage();
			rm.setCode("0");
			rm.setUserID(userID) ;
			rm.setPayType(payType);
			rm.setPayStr(payStr);
			modelMap.put("res", rm);
		}
		else if(payType.equals("1")){
			SortedMap<Object,Object> sParaTemp=new TreeMap<Object,Object>();
			sParaTemp.put("appid", ConfigUtil.APPID);
			sParaTemp.put("mch_id", ConfigUtil.MCH_ID);
			sParaTemp.put("nonce_str", PayCommonUtil.CreateNoncestr());
			sParaTemp.put("body", "recharge");
			sParaTemp.put("out_trade_no", out_trade_no);
			sParaTemp.put("total_fee", moneyString);
			sParaTemp.put("spbill_create_ip", "");
			sParaTemp.put("notify_url", ConfigUtil.NOTIFY_URL);
			sParaTemp.put("trade_type", "APP");
			String signString = PayCommonUtil.createSign("UTF-8", sParaTemp);
			sParaTemp.put("sign", signString);
			
			String requestXmlString = PayCommonUtil.getRequestXml(sParaTemp);
			
			logger.error("requestXmlString : " + requestXmlString);
			
			String responseString = CommonUtil.httpsRequest(ConfigUtil.UNIFIED_ORDER_URL, "POST", requestXmlString);
			
			Map responseMap = null ;
			try {
				responseMap = XMLUtil.doXMLParse(responseString);
			} catch (JDOMException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			if(responseMap!=null){
				if(responseMap.get("return_code").equals("SUCCESS")){
					
				}
			}
			long timeStamp = System.currentTimeMillis()/1000;
//			//客户端sign生成
			SortedMap<Object,Object> sParaTemp2=new TreeMap<Object,Object>();
			sParaTemp2.put("appid", ConfigUtil.APPID);
			sParaTemp2.put("partnerid", ConfigUtil.MCH_ID);
			sParaTemp2.put("prepayid", (String)responseMap.get("prepay_id"));
			sParaTemp2.put("package", "Sign=WXPay");
			sParaTemp2.put("noncestr", (String)responseMap.get("nonce_str"));
			sParaTemp2.put("timestamp", timeStamp);
			String signString2 = PayCommonUtil.createSign("UTF-8", sParaTemp2);
			
			
			RechargeForWeixinMessage rf = new RechargeForWeixinMessage();
			rf.setPackageValue("Sign=WXPay");
			rf.setPartnerId(ConfigUtil.MCH_ID);
			rf.setNonceStr((String)responseMap.get("nonce_str"));
			rf.setPrepayId((String)responseMap.get("prepay_id"));
			rf.setSign(signString2);
			rf.setTimeStamp(timeStamp+"");
//			logger.error("=============  "+(String)responseMap.get("nonce_str"));
			RechargeForWeixinJson rjs = new RechargeForWeixinJson();
			rjs.setPayStr(rf) ;
			rjs.setCode("0");
			rjs.setUserID(userID) ;
			rjs.setPayType(payType);
			modelMap.put("res", rjs);
		}
		
		
		
		return modelMap;
	}
	
	//订单支付平台结算接口
	private Map<String , Object> payorder(PayJsonMainBean jsonObject){
		Map<String , Object> modelMap = new HashMap<String , Object>();
		String userID = jsonObject.getUserID();
		String payType = jsonObject.getPayType();
		String channelID  = jsonObject.getChannelID();
		String thdOrderID = jsonObject.getThdOrderID();
		String out_trade_no = UtilDate.getOrderNum() ; ;
		String subject = "支付";
		
		TOrder order = new TOrder() ;
		order.setChannelid(channelID);
		order.setThdorderid(thdOrderID);
		
		TOrder order2 = pamentlogService.selectByInfo(order);
		
		TPamentlog  tp = new TPamentlog();
		tp.setOuttradesn(out_trade_no) ;
		tp.setPayamount(order2.getMoney());
		tp.setUserid(Integer.valueOf(userID));
		tp.setOrderid(order2.getOrderid()+"");
		tp.setPaytype(payType);
		//获取充值账户号
		tp.setUseraccountid(0);
		tp.setPaymentname("订单支付");
		tp.setPaytotype("10");
		pamentlogService.insertPamentlog(tp,Integer.valueOf(userID));
		
		String payStr = "" ;
		
		if(payType.equals("2")){
			Map<String, String> sParaTemp = new HashMap<String, String>();
			sParaTemp.put("service", AlipayConfig.service);
	        sParaTemp.put("partner", AlipayConfig.partner);
	        sParaTemp.put("seller_id", AlipayConfig.seller_id);
	        sParaTemp.put("_input_charset", AlipayConfig.input_charset);
			sParaTemp.put("payment_type", AlipayConfig.payment_type);
			sParaTemp.put("notify_url", AlipayConfig.notify_url);
			sParaTemp.put("out_trade_no", out_trade_no);
			sParaTemp.put("subject", subject);
			BigDecimal a= new BigDecimal(order2.getMoney());
			BigDecimal c= new BigDecimal("100");
			BigDecimal bigDecimal = a.divide(c,2,BigDecimal.ROUND_HALF_EVEN );
			sParaTemp.put("total_fee", bigDecimal+"");
			logger.error("支付宝  total_fee:" +order2.getMoney()+"处理后金额:"+ bigDecimal  );
			payStr = AlipaySubmit.buildStr(sParaTemp) ;
			
			RechargeMessage rm = new RechargeMessage();
			rm.setCode("0");
			rm.setUserID(userID) ;
			rm.setPayType(payType);
			rm.setPayStr(payStr);
			modelMap.put("res", rm);
		}else if(payType.equals("1")){
			SortedMap<Object,Object> sParaTemp=new TreeMap<Object,Object>();
			sParaTemp.put("appid", ConfigUtil.APPID);
			sParaTemp.put("mch_id", ConfigUtil.MCH_ID);
			sParaTemp.put("nonce_str", PayCommonUtil.CreateNoncestr());
			sParaTemp.put("body", "订单");
			sParaTemp.put("out_trade_no", out_trade_no);
			sParaTemp.put("total_fee", order2.getMoney());
			sParaTemp.put("spbill_create_ip", "");
			sParaTemp.put("notify_url", ConfigUtil.NOTIFY_URL);
			sParaTemp.put("trade_type", "APP");
			
			String signString = PayCommonUtil.createSign("UTF-8", sParaTemp);
			sParaTemp.put("sign", signString);
			
			String requestXmlString = PayCommonUtil.getRequestXml(sParaTemp);
			
			String responseString = CommonUtil.httpsRequest(ConfigUtil.UNIFIED_ORDER_URL, "POST", requestXmlString);
			
			Map responseMap = null ;
			try {
				responseMap = XMLUtil.doXMLParse(responseString);
			} catch (JDOMException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			if(responseMap!=null){
				if(responseMap.get("return_code").equals("SUCCESS")){
					
				}
			}
			long timeStamp = System.currentTimeMillis()/1000;
//			//客户端sign生成
			SortedMap<Object,Object> sParaTemp2=new TreeMap<Object,Object>();
			sParaTemp2.put("appid", ConfigUtil.APPID);
			sParaTemp2.put("partnerid", ConfigUtil.MCH_ID);
			sParaTemp2.put("prepayid", (String)responseMap.get("prepay_id"));
			sParaTemp2.put("package", "Sign=WXPay");
			sParaTemp2.put("noncestr", (String)responseMap.get("nonce_str"));
			sParaTemp2.put("timestamp", timeStamp);
			String signString2 = PayCommonUtil.createSign("UTF-8", sParaTemp2);
			
			
			RechargeForWeixinMessage rf = new RechargeForWeixinMessage();
			rf.setPackageValue("Sign=WXPay");
			rf.setPartnerId(ConfigUtil.MCH_ID);
			rf.setNonceStr((String)responseMap.get("nonce_str"));
			rf.setPrepayId((String)responseMap.get("prepay_id"));
			rf.setSign(signString2);
			rf.setTimeStamp(timeStamp+"");
			
			RechargeForWeixinJson rjs = new RechargeForWeixinJson();
			rjs.setPayStr(rf) ;
			rjs.setCode("0");
			rjs.setUserID(userID) ;
			rjs.setPayType(payType);
			modelMap.put("res", rjs);
		}
		
		return modelMap;
	}
	
	
	

	//余额支付结算接口
}
